package dimension.starry.item.typeInterface.WeaponType;

import dimension.starry.constants.WeaponAttribute;
import dimension.starry.constants.WeaponExp;
import dimension.starry.item.typeInterface.ALLItemType;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.text.Text;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public interface WeaponType extends ALLItemType {

    String WEAPON_LEVEL = "weapon_level";
    String WEAPON_MAX_LEVEL = "weapon_max_level";
    String WEAPON_EXP = "weapon_exp";
    String WEAPON_MERGE = "weapon_merge";

    static int getLevel(ItemStack itemStack) {
        if (itemStack.getItem() instanceof WeaponType) {
            NbtCompound compoundNBT = itemStack.getOrCreateNbt();
            return compoundNBT.getInt(WEAPON_LEVEL);
        }
        return 0;
    }

    static int getMaxLevel(ItemStack itemStack) {
        if (itemStack.getItem() instanceof WeaponType) {
            NbtCompound compoundNBT = itemStack.getOrCreateNbt();
            return compoundNBT.getInt(WEAPON_MAX_LEVEL) == 0 ? 20 : compoundNBT.getInt(WEAPON_MAX_LEVEL);
        }
        return 20;
    }

    static int getExp(ItemStack itemStack) {
        if (itemStack.getItem() instanceof WeaponType) {
            NbtCompound compoundNBT = itemStack.getOrCreateNbt();
            return compoundNBT.getInt(WEAPON_EXP);
        }
        return 0;
    }

    static int getMergeCount(ItemStack itemStack) {
        if (itemStack.getItem() instanceof WeaponType) {
            NbtCompound compoundNBT = itemStack.getOrCreateNbt();
            return compoundNBT.getInt(WEAPON_MERGE) == 0 ? 1 : compoundNBT.getInt(WEAPON_MERGE);
        }
        return 1;
    }

    static LinkedHashMap<WeaponAttribute, Double> getAttributeMap(ItemStack itemStack) {
        int level = getLevel(itemStack);
        if (itemStack.getItem() instanceof WeaponType) {
            WeaponType weaponType = (WeaponType) itemStack.getItem();
            LinkedHashMap<WeaponAttribute, Double> result = new LinkedHashMap<>();
            LinkedHashMap<WeaponAttribute, Double> attributeMap = weaponType.getBaseAttributeMap();
            LinkedHashMap<WeaponAttribute, List<Double>> levelUpAttributeMap = weaponType.getLevelUpAttributeMap();
            for (Map.Entry<WeaponAttribute, Double> entry : attributeMap.entrySet()) {
                List<Double> levelUpList = levelUpAttributeMap.get(entry.getKey());
                if (levelUpList == null) {
                    return attributeMap;
                } else if (level - 1 >= levelUpList.size()) {
                    result.put(entry.getKey(), levelUpList.get(levelUpList.size() - 1) + entry.getValue());
                } else if (level - 1 < 0) {
                    result.put(entry.getKey(), entry.getValue());
                } else {
                    result.put(entry.getKey(), levelUpList.get(level - 1) + entry.getValue());
                }
            }
            return result;
        }
        return new LinkedHashMap<>();
    }

    static void upgrade(ItemStack itemStack) {
        if (itemStack.getItem() instanceof WeaponType) {
            NbtCompound compoundNBT = itemStack.getOrCreateNbt();
            compoundNBT.putInt(WEAPON_LEVEL, getLevel(itemStack) + 1);
            itemStack.setNbt(compoundNBT);
            setExp(itemStack, 0);
        }
    }

    static void setExp(ItemStack itemStack, int count) {
        if (itemStack.getItem() instanceof WeaponType) {
            NbtCompound nbtCompound = itemStack.getOrCreateNbt();
            nbtCompound.putInt(WEAPON_EXP, count);
            itemStack.setNbt(nbtCompound);
        }
    }

    static void addExp(ItemStack itemStack, int count) {
        if (itemStack.getItem() instanceof WeaponType) {
            int currentExp = getExp(itemStack) + count;
            int needExp = WeaponExp.getNeedExp((WeaponType) itemStack.getItem(), getLevel(itemStack));
            while (currentExp >= needExp && getLevel(itemStack) < getMaxLevel(itemStack)) {
                currentExp = currentExp - needExp;
                upgrade(itemStack);
                needExp = WeaponExp.getNeedExp((WeaponType) itemStack.getItem(), getLevel(itemStack));
            }
            setExp(itemStack, currentExp);
        }
    }

    static void mergeWeapon(ItemStack itemStack) {
        if (itemStack.getItem() instanceof WeaponType) {
            NbtCompound nbtCompound = itemStack.getNbt();
            if (nbtCompound == null) {
                nbtCompound = new NbtCompound();
                nbtCompound.putInt(WEAPON_MERGE, 2);
            } else {
                nbtCompound.putInt(WEAPON_MERGE, getMergeCount(itemStack) + 1);
            }
            itemStack.setNbt(nbtCompound);
        }
    }

    static void updateMaxLevel(ItemStack itemStack) {
        if (itemStack.getItem() instanceof WeaponType) {
            NbtCompound nbtCompound = itemStack.getNbt();
            if (nbtCompound == null) {
                nbtCompound = new NbtCompound();
                nbtCompound.putInt(WEAPON_MAX_LEVEL, 30);
            } else {
                nbtCompound.putInt(WEAPON_MAX_LEVEL, getLevel(itemStack) + 10);
            }
            itemStack.setNbt(nbtCompound);
        }
    }

    LinkedHashMap<WeaponAttribute, Double> getBaseAttributeMap();

    LinkedHashMap<WeaponAttribute, List<Double>> getLevelUpAttributeMap();

    List<Text> getDescription();

}
